<?php


namespace app\pay\controller;

use think\Controller;
use think\Db;
use think\facade\Session;
use think\Request;
use jwt\JWT;
use think\facade\Cache;
/*
 * {
    "code": 0,
    "msg": "success",
    "data": ""
}
 * */
class Alipayapp extends Pay
{
    protected $merchant_id="3172027890277769";
    protected $private_key="";
    protected $public_key="-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+Vd3j0McNfR3VvT7mZp/7M6UL\nFJSc3dh3/56JP8DZk+cDlXC2LR0z0OELJeyTitFeBjpPWzWH3OOFI/OL3nD5/oNZ\nfK+wHd4Tzxj2SdWlyuqRhNv3xG2obUUYZ9urUvkCvxL1SclaXW7cq22V/TTNSgJq\n7CGdc+q/XLNqcmLt7QIDAQAB\n-----END PUBLIC KEY-----\n";

    public function __construct()
    {
        parent::__construct();
        $this->private_key=file_get_contents(ROOT_PATH."extend/jwt/rsa_private_key.pem");
        $this->public_key=file_get_contents(ROOT_PATH."extend/jwt/rsa_public_key.pem");
    }

    /**
     * @Date   2019-01-04
     * @param  string     $config  通道配置信息
     * @param  string     $order_no   订单信息
     * @param  string     $paymoney 支付金额
     * @return [type]               [description]
     */
    public function init($order_no)
    {
        header("content-type:text/html;charset=utf-8");
        if($order_no==''){
            return json(['error'=>1,'msg'=>'订单号错误']);
        }

        $list = Db::name('PayUpgrade')->where('upgrade_form_no',$order_no)->where('upgrade_state',0)->find();
        if(empty($list))
        {
            return json(['error'=>1,'msg'=>'订单信息错误']);
        }
        $notify = 'http://'.$_SERVER['SERVER_NAME'].'/pay/Alipayapp/notify';
        $money = $list['upgrade_money'];

        $Payment = Db::name('Payment')->where('payment_id',$list['upgrade_pay_id'])->find();
        if(empty($Payment))
        {
            return json(['error'=>1,'msg'=>'支付通道信息错误']);
        }

        $pconfig = configJsonToArr($Payment['payment_config']);

    //halt($order_no);
        // 下单必要的参数
        $params['pay_type']           = "alipay.scan";
        $params['nonce_str']        = uniqid();//随机数
        $params['mch_trade_id']     = $order_no;  // 本地订单
        $params['total_fee']        = $money*100;  // 充值金额 支付单位为分
        $params['body']             = '会员升级V1';    //商品描述
        $params['spbill_create_ip'] = $this->get_client_ip();
        $params['notify_url']       = $notify;


        //统一下单
        $result = $this->unifiedOrder($params,"https://api.pooul.com/v2/pay?merchant_id={$this->merchant_id}");
        return json($result);
//        if($result["code"]!=0){
//            return  $result["msg"];
//        }else{
//            header("location:".$result["data"]["code_url"]);exit;
//        }
    }

    /**
     * 统一下单
     * @param  $params    下单参数
     */
    public function unifiedOrder($params,$apiUrl){
        //进行jwt加密
        $jwt = $this->jwtEncode($params);
        //发起请求
        $authorization = $this->loginAuth();
        $header = ["Content-Type: text/plain","Authorization: {$authorization}"];
        $access_token = $this->postCurl($apiUrl,$jwt,$header);
        if(strpos($access_token,"code")>0){
            return json_decode($access_token,true);
        }
        //机密jwt
        $json = $this->jwtDecode($access_token);
        return $json;
    }


    /**
     * 获取头部信息
     */
    private function loginAuth(){
        $Authorization = Cache::get("authorization");
        if(!$Authorization){
            $apiUrl = "https://api.pooul.com/web/user/session/login_name";
            $data=json_encode(["login_name"=>"18638109929","password"=>"yy18638109929"]);
            $header = ["Content-Type: application/json"];
            $respond = $this->postJson($apiUrl,$data,$header);
            if(!$respond){
                return false;
            }
            $respond = explode(":",$respond);
            $respond = $respond[9];
            $respond = str_replace(" ","",$respond);
            $Authorization = substr($respond,0,40);
            Cache::set("authorization",$Authorization,30*60);
        }
        return $Authorization;
    }



    /**
     * jwt加密请求数据
     */
    private function jwtEncode($param){
        $jwt = JWT::encode($param, $this->private_key, 'RS256');
        return $jwt;
    }


    /**
     * jwt解密返回数据
     *
     */
    private function jwtDecode($jwt){
        $decoded = JWT::decode($jwt, $this->public_key, ['RS256']); //解密同时验签
        $json = json_encode($decoded,JSON_UNESCAPED_SLASHES );
        $res = json_decode($json,true);
        return $res;
    }



    private function get_client_ip(){
        if ($_SERVER['REMOTE_ADDR']) {
            $cip = $_SERVER['REMOTE_ADDR'];
        } elseif (getenv("REMOTE_ADDR")) {
            $cip = getenv("REMOTE_ADDR");
        } elseif (getenv("HTTP_CLIENT_IP")) {
            $cip = getenv("HTTP_CLIENT_IP");
        } else {
            // $cip = "unknown";
            $cip = "127.0.0.1";
        }
        return $cip;
    }


    // 会员升级回调
    public function notify(){
        $jwt =  file_get_contents("php://input");
		$this->save_log('logs/alipayapplog','回调数据：'.var_export($jwt,true));
        $data = $this->jwtDecode($jwt);
        if($data["code"] != 0){
        	echo "fail";exit;
		}
		//echo "fail";exit;
        $data = $data["data"];

        if($data["trade_state"]==0) {
            $this->save_log('alipayapplog','订单验签成功！');
            // 执行回调程序
            $amount = $data["total_fee"]/100;
            $res = $this->Notifys($data["mch_trade_id"], $data["trade_id"], $amount);
            if($res['error']==0){
                $this->save_log('alipayapplog','回调执行成功');
                echo "success";exit;
            }else{
                $this->save_log('alipayapplog','回调执行失败！：'.$res['msg']);
                echo "fail";exit;
            }
        }else{
            $this->save_log('alipayapplog','支付失败：'.json_encode($data));
            echo "fail";exit;
        }
    }



    /**
     * 以post方式提交xml到对应的接口url
     *
     * @param string $xml  需要post的xml数据
     * @param string $url  url
     * @param bool $useCert 是否需要证书，默认不需要
     * @param int $second   url执行超时时间，默认30s
     * @throws WxPayException
     */
    private function postCurl($url, $data, $header){
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER,$header);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $res = curl_exec($ch);
        curl_close ($ch);
        return $res;
    }


    private function postJson($url,$json,$header){
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);

        curl_setopt($ch,CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER,$header);
        //设置header
        curl_setopt($ch, CURLOPT_HEADER, true);
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

        //post提交方式
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
        //运行curl
        $data = curl_exec($ch);
        //返回结果
        if($data){
            // 获得响应结果里的：头大小
            $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
            // 根据头大小去获取头信息内容
            $header = substr($data, 0, $headerSize);
            curl_close($ch);
            return $header;
        } else {
            $error = curl_errno($ch);
            curl_close($ch);
            return false;
        }
    }



    /*
     * 记录日志文件
     * linux 请补全路径
     */
    private function save_log($path, $msg){
        if (! is_dir($path)) {
            mkdir($path,0777,true);
        }
        $filename = $path . '/' . date('YmdHi') . '.txt';
        $content = date("Y-m-d H:i:s")."\r\n".$msg."\r\n \r\n \r\n ";
        file_put_contents($filename, $content, FILE_APPEND);
    }
}